package com.bsdsma.fengheguaiapp.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO;
import com.bsdsma.fengheguaiapp.constants.ErrorCodes;
import com.bsdsma.fengheguaiapp.dto.DataGroupByDateDto;
import com.bsdsma.fengheguaiapp.dto.PageRetDto;
import com.bsdsma.fengheguaiapp.dto.UserAddDto;
import com.bsdsma.fengheguaiapp.dto.UserQueryDto;
import com.bsdsma.fengheguaiapp.entity.User;
import com.bsdsma.fengheguaiapp.enums.Role;
import com.bsdsma.fengheguaiapp.exceptionhandler.GlobalRuntimeException;
import com.bsdsma.fengheguaiapp.mapper.UserMapper;
import com.bsdsma.fengheguaiapp.service.UserService;
import com.bsdsma.fengheguaiapp.utils.CustomerBeanUtils;
import com.bsdsma.fengheguaiapp.utils.DateUtils;
import com.bsdsma.fengheguaiapp.utils.PageRetUtils;
import com.bsdsma.fengheguaiapp.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.PostConstruct;
import java.util.Collections;
import java.util.Date;
import java.util.List;

@Slf4j
@Service
public class UserServiceImpl implements UserService {

    /**
    * 使用Spring注入Mybatis操作对象
    */
    @Autowired
    private UserMapper userMapper;
    @Value("${data-init.user.account}")
    private String initUserAccount;
    @Value("${data-init.user.password}")
    private String initUserPassword;
    @Value("${data-init.user.name}")
    private String initUserName;

    @Override
    public PageRetDto<User> query(UserQueryDto dto) {
        Role role = dto.getRole();
        User user = new User();
        if(null != role){
            user.setRole(role.getValue());
        }
        String account = dto.getAccount();
        if(!StringUtils.isBlank(account)){
            user.setAccount(account);
        }
        String name = dto.getName();
        String cellphoneNumber = dto.getCellphoneNumber();
        if(!StringUtils.isBlank(cellphoneNumber)){
            user.setCellphoneNumber(cellphoneNumber);
        }
        user.setStatus(0);
        QueryWrapper<User> wrapper = new QueryWrapper<>(user);
        if(!StringUtils.isBlank(name)){
            wrapper.like("name", "%" + name + "%");
        }
        IPage<User> pageData = userMapper.selectPage(new PageDTO<>(dto.getPage(), dto.getSize()), wrapper);
        return PageRetUtils.parse(pageData);
    }

    @Override
    public User add(UserAddDto dto) {
        String account = dto.getAccount();
        String password = dto.getPassword();
        String cellphoneNumber = dto.getCellphoneNumber();
        String name = dto.getName();
        Role role = Role.get(dto.getRole());
        if(null == role){
            throw new GlobalRuntimeException(ErrorCodes.PARAMS_ERROR, "角色不存在");
        }
        if(StringUtils.isBlank(account)){
            throw new GlobalRuntimeException(ErrorCodes.PARAMS_ERROR, "请填写登录账号");
        }
        if(StringUtils.isBlank(password)){
            throw new GlobalRuntimeException(ErrorCodes.PARAMS_ERROR, "请填写登录密码");
        }
        if(StringUtils.isBlank(name)){
            throw new GlobalRuntimeException(ErrorCodes.PARAMS_ERROR, "请填写姓名");
        }
        User existsUser = this.getByAccount(account);
        if(null != existsUser){
            throw new GlobalRuntimeException(ErrorCodes.OBJ_ALREADY_EXISTS, "该登录账号已存在");
        }
        if(!StringUtils.isBlank(cellphoneNumber)){
            existsUser = this.getByCellphoneNumber(cellphoneNumber);
            if(null != existsUser){
                throw new GlobalRuntimeException(ErrorCodes.OBJ_ALREADY_EXISTS, "该手机号已存在");
            }
        }
        User user = CustomerBeanUtils.copyPropertiesClass(dto, User.class);
        user.setStatus(0);
        user.setRole(role.getValue());
        user.setCt(DateUtils.getNow());
        user.setUt(DateUtils.getNow());
        user.setCellphoneNumber(StringUtils.isBlank(cellphoneNumber) ? "" : cellphoneNumber);
        userMapper.insert(user);
        return user;
    }

    @Override
    public User update(Long id, UserAddDto dto) {
        User user = this.getById(id);
        if(null == user){
            throw new GlobalRuntimeException(ErrorCodes.OBJ_NOT_EXISTS, "用户不存在");
        }
        String account = dto.getAccount();
        String cellphoneNumber = dto.getCellphoneNumber();
        if(StringUtils.isBlank(account)){
            throw new GlobalRuntimeException(ErrorCodes.PARAMS_ERROR, "请填写登录账号");
        }
        User existsUser = this.getByAccount(account);
        if(null != existsUser && !existsUser.getId().equals(user.getId())){
            throw new GlobalRuntimeException(ErrorCodes.OBJ_ALREADY_EXISTS, "该登录账号已存在");
        }
        if(!StringUtils.isBlank(cellphoneNumber)){
            existsUser = this.getByCellphoneNumber(cellphoneNumber);
            if(null != existsUser && !existsUser.getId().equals(user.getId())){
                throw new GlobalRuntimeException(ErrorCodes.OBJ_ALREADY_EXISTS, "该手机号已存在");
            }
        }
        CustomerBeanUtils.copyProperties(dto, user);
        Role role = Role.get(dto.getRole());
        if(null != role){
            user.setRole(role.getValue());
        }
        userMapper.updateById(user);
        return user;
    }

    @Override
    public User getByAccount(String account) {
        // 声明一个User对象
        User user = new User();
        // 设置账号
        user.setAccount(account);
        user.setStatus(0);
        return userMapper.selectOne(new QueryWrapper<>(user));
    }

    @Override
    public User getByCellphoneNumber(String cellphoneNumber) {
        User user = new User();
        user.setCellphoneNumber(cellphoneNumber);
        user.setStatus(0);
        return userMapper.selectOne(new QueryWrapper<>(user));
    }

    @Override
    public User getById(Long id) {
        return userMapper.selectById(id);
    }

    @Override
    public List<User> listByRole(Role role) {
        User user = new User();
        user.setRole(role.getValue());
        user.setStatus(0);
        return userMapper.selectList(new QueryWrapper<>(user));
    }

    @Override
    public User getRandomOneByRole(Role role) {
        List<User> users = this.listByRole(role);
        if(CollectionUtils.isEmpty(users)){
            return null;
        }
        Collections.shuffle(users);
        return users.get(0);
    }

    @Override
    public void delete(Long id) {
        User entity = this.getById(id);
        if(null == entity){
            throw new GlobalRuntimeException(ErrorCodes.OBJ_NOT_EXISTS, "用户不存在");
        }
        entity.setStatus(-1);
        entity.setUt(DateUtils.getNow());
        userMapper.updateById(entity);
    }

    @Override
    public int updateById(User entity) {
        return userMapper.updateById(entity);
    }

    @Override
    public Long count() {
        User entity = new User();
        entity.setStatus(0);
        return userMapper.selectCount(new QueryWrapper<>(entity));
    }

    @Override
    public List<DataGroupByDateDto> countByDay(Date beginDate, Date endDate) {
        return userMapper.countByDay(beginDate, endDate);
    }

    @PostConstruct
    public void initUser(){
        if(StringUtils.isBlank(this.initUserAccount)
                || StringUtils.isBlank(this.initUserPassword)
                || StringUtils.isBlank(this.initUserName)){
            return;
        }
        log.info("正在初始化用户[{}]-[{}]-[{}]，如果你希望跳过此步骤，" +
        "请将\"application-dev.yml\"中的\"data-init\"配置去掉",
        this.initUserAccount, this.initUserPassword, this.initUserName);
        User initUser = this.getByAccount(this.initUserAccount);
        if(null != initUser){
            log.info("账号[{}]已初始化到系统，不再进行初始化", this.initUserAccount);
            return;
        }
        UserAddDto dto = new UserAddDto();
        dto.setAccount(this.initUserAccount);
        dto.setPassword(this.initUserPassword);
        dto.setName(this.initUserName);
        dto.setRole(Role.SUPER_ADMIN.getValue());
        this.add(dto);
    }

    @Override
    public User login(String username, String password) {
        if (StringUtils.isBlank(username)) {
            throw new GlobalRuntimeException(ErrorCodes.PARAMS_ERROR, "请输入用户名");
        }
        if (StringUtils.isBlank(password)) {
            throw new GlobalRuntimeException(ErrorCodes.PARAMS_ERROR, "请输入密码");
        }

        // 查询用户信息
        User query = new User();
        query.setAccount(username);
        query.setStatus(0);
        User user = userMapper.selectOne(new QueryWrapper<>(query));

        if (user == null) {
            throw new GlobalRuntimeException(ErrorCodes.PARAMS_ERROR, "用户名或密码错误");
        }

        // 验证密码
        if (!password.equals(user.getPassword())) {
            throw new GlobalRuntimeException(ErrorCodes.PARAMS_ERROR, "用户名或密码错误");
        }

        return user;
    }
}